package com.flaskpy.web.eternity.auth.jwt.service.impl;

import cn.hutool.core.util.StrUtil;
import com.flaskpy.web.eternity.auth.jwt.constant.CommonConstant;
import com.flaskpy.web.eternity.auth.jwt.entiry.JwtPayLoad;
import com.flaskpy.web.eternity.auth.jwt.service.IJwtAuthicationService;
import com.flaskpy.web.eternity.auth.jwt.service.IOnLineService;
import com.flaskpy.web.eternity.auth.jwt.util.TokenProvider;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.context.HttpRequestResponseHolder;
import org.springframework.security.web.context.SecurityContextRepository;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
//SecurityContextPersistenceFilter 负责从SecurityContextRepository中
//获取SecurityContext 和保存 SecurityContext
//SecurityContext保存Authnxxxxxn信息

/**
 * 信息保存容器
 * sam:(如果你不懂可以参考 SecurityContextPersistenceFilter这个过滤器)
 */
public class JwtContextRepositoryImpl implements SecurityContextRepository {
    @Autowired
    private TokenProvider tokenProvider;
    @Autowired
    private IJwtAuthicationService jwtAuthicationService;
    @Autowired
    private IOnLineService onLineService;
    @SneakyThrows
    @Override
    public SecurityContext loadContext(HttpRequestResponseHolder httpRequestResponseHolder) {

        HttpServletRequest request = httpRequestResponseHolder.getRequest();
        Authentication authentication=null;
        String token=this.getToken(httpRequestResponseHolder.getRequest());
        if(!StrUtil.isBlank(token)){
            request.setAttribute(CommonConstant.JWT_TOKEN,token);
            JwtPayLoad jwtSimpleDTO=tokenProvider.tokeToJWTContentDTO(token);
            request.setAttribute(CommonConstant.JWT_DTO,jwtSimpleDTO);
            if(this.onLineService.checkNonExpires(token)){
                authentication=this.jwtAuthicationService.toAuthentication(jwtSimpleDTO);
                this.onLineService.renewal(token,authentication);
            }else{
                    throw new ExpiredJwtException(null,null,"已过续约期");
            }
        }
        SecurityContext context = SecurityContextHolder.createEmptyContext();
        context.setAuthentication(authentication);
        return context;
    }

    @Override
    public void saveContext(SecurityContext securityContext, HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) {

        //jwt令牌不需要保存在客户端
        //HttpSessionSecurityContextRepository
        // NullSecurityContextRepository
        //SecurityContextPersistenceFilter
    }

    @Override
    public boolean containsContext(HttpServletRequest httpServletRequest) {
        return !StrUtil.isEmpty(getToken(httpServletRequest));
    }
    private String getToken(HttpServletRequest request){
        String token= request.getHeader("Authorization");
        if(!StrUtil.isBlank(token) && token.contains(" ")){

            token=token.trim().split(" ")[1];
        }
        return token;
    }
}
